package com.fengwk.cv4j.view.ind;

import org.nd4j.linalg.api.ndarray.INDArray;

import com.fengwk.cv4j.compute.Compute;
import com.fengwk.cv4j.compute.ind.INDCompute;
import com.fengwk.cv4j.factory.ViewFactory;
import com.fengwk.cv4j.utils.Nd4jUtils;
import com.fengwk.cv4j.view.View;
import com.fengwk.cv4j.view.ViewImpl;
import com.fengwk.support.exception.BaseException;

/**
 * 矩阵乘
 * (n,m)(m,j)=(n,j)
 * 
 * @author fengwk
 *
 */
public class INDMmulView extends ViewImpl<INDArrayWrap> {

	private static final long serialVersionUID = -5537388589036636350L;

	public INDMmulView(Compute<INDArrayWrap> compute, ViewFactory<INDArrayWrap> factory, @SuppressWarnings("unchecked") View<INDArrayWrap>...vs) {
		super(compute, factory, vs);
		checkVs(2, vs);
	}

	@Override
	public INDArrayWrap compute0() {
		return ((INDCompute) c()).mmul(t(0), t(1));
	}

	@Override
	protected View<INDArrayWrap> gradient0(int idx) {
		INDArray arr0 = t(0).arr();
		INDArray arr1 = t(1).arr();
		if (arr0 == null || arr1 == null)
			throw new BaseException("arr0 == null || arr1 == null");
		if (idx == 0) 
			return f().of(new INDArrayWrap(Nd4jUtils.sum0(arr1, arr1.rank() - 1).transpose().broadcast(arr0.shape())));
		if (idx == 1)
			return f().of(new INDArrayWrap(Nd4jUtils.sum0(arr0, arr0.rank() - 2).transpose().broadcast(arr1.shape())));
		throw new BaseException("idx != 0 && idx != 1");
	}

	@Override
	public String toString() {
		return "mmul";
	}
	
}
